using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication4
{



    public partial class CompaingView : Form, ICampaigns
    {

        private enum ScheduleBy
        {
            LandTime,
            StartTime
        }
        private ScheduleBy scheduleBy = ScheduleBy.StartTime;

        /// <summary>
        /// Holds the target to copy (ie in the clip board). (when the user chose 'copy target')
        /// </summary>
        Target targetToCopy = null;
        /// <summary>
        /// Holds the attacks to copy. (when the user chose 'copy attack')
        /// </summary>
        List<Attack> attacksToCopy = null;

        public class CONSTS
        {

            public class dgvAttacks
            {
                public class ColIndexes
                {
                    public static int AttackOrder = 0;
                    public static int AttackingVillage = 1;
                    public static int TargetVillage = 2;
                    public static int Duration = 3;
                    public static int Unit = 4;
                    public static int Launch = 5;
                    public static int LandTime = 6;
                    public static int Description = 7;
                }
            }

            public class dgvExecutingAttacks
            {
                public class ColIndexes
                {
                    public static int AttackingVillage = 0;
                    public static int TargetVillage = 1;
                    public static int Duration = 2;
                    public static int Unit = 3;
                    public static int LaunchTime = 4;
                    public static int LaunchIn = 5;
                    public static int LandTime = 6;
                    public static int Description = 7;
                }
            }
        }


        public CompaingView()
        {
            InitializeComponent();


            DataGridViewTextBoxColumn columnPriority = new DataGridViewTextBoxColumn();
            columnPriority.Name = "Attack Order";
            columnPriority.Width = 40;            
            columnPriority.ValueType = Type.GetType("System.Int32");
            columnPriority.MinimumWidth = 40;
            dgvAttacks.Columns.Add(columnPriority);

            DataGridViewTextBoxColumn columnAttackingVillage = new DataGridViewTextBoxColumn();
            columnAttackingVillage.Name = "Attacking Village";
            columnAttackingVillage.Width = 130;
            columnAttackingVillage.ReadOnly = true;
            columnAttackingVillage.ValueType = Type.GetType("System.String");
            dgvAttacks.Columns.Add(columnAttackingVillage);

            DataGridViewTextBoxColumn columnTargetVillage = new DataGridViewTextBoxColumn();
            columnTargetVillage.Name = "Target Village";
            columnTargetVillage.Width = 130;
            columnTargetVillage.ReadOnly = true;
            columnTargetVillage.ValueType = Type.GetType("System.String");
            dgvAttacks.Columns.Add(columnTargetVillage);

            DataGridViewTextBoxColumn columnDuration = new DataGridViewTextBoxColumn();
            columnDuration.Name = "Duration";
            columnDuration.Width = 50;
            columnDuration.ReadOnly = true;
            columnDuration.ValueType = Type.GetType("System.TimeSpan");
            dgvAttacks.Columns.Add(columnDuration);

            DataGridViewComboBoxColumn columnAttackWith = new DataGridViewComboBoxColumn();
            Unit[] units = new Unit[Worlds.currentWorld.Units.Count];
            Worlds.currentWorld.Units.Values.CopyTo(units, 0);
            columnAttackWith.Name = "Unit";
            columnAttackWith.Width = 75;
            columnAttackWith.DataSource = units;
            columnAttackWith.DataPropertyName = "Name";
            columnAttackWith.DisplayMember = "Name";
            columnAttackWith.ValueType = Type.GetType("System.String");
            columnAttackWith.SortMode = DataGridViewColumnSortMode.Automatic;
            dgvAttacks.Columns.Add(columnAttackWith);

            DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
            col.Name = "Launch";
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.DateTime");
            dgvAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Land Time";
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.DateTime");
            dgvAttacks.Columns.Add(col);

            DataGridViewTextBoxColumn columnDescription = new DataGridViewTextBoxColumn();
            columnDescription.Name = "Description";
            columnDescription.Width = 150;
            columnDescription.ReadOnly = false;
            columnDescription.ValueType = Type.GetType("System.String");
            dgvAttacks.Columns.Add(columnDescription);


            //
            // Executing attacks
            //
            col = new DataGridViewTextBoxColumn();
            col.Name = "Attacking Village";
            col.Width = 145;
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.String");
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Width = 145;
            col.Name = "Target Village";
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.String");
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Duration";
            col.Width = 60;
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.TimeSpan");
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Unit";
            col.Width = 60;
            col.ReadOnly = true;
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Launch Time";
            col.ReadOnly = true;
            col.Width = 100;
            col.ValueType = Type.GetType("System.DateTime");
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Launch In";
            col.Width = 70;
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.TimeSpan");
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Land Time";
            col.Width = 100;
            col.ReadOnly = true;
            col.ValueType = Type.GetType("System.DateTime");
            dgvExecutingAttacks.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name = "Description";
            col.Width = 150;
            col.ReadOnly = false;
            col.ValueType = Type.GetType("System.String");
            dgvExecutingAttacks.Columns.Add(col);

//            SetScheduleBy(ScheduleBy.StartTime);

            cbTimeFormatToUse.Items.Add(App.TimeFormat.Local);
            cbTimeFormatToUse.Items.Add(App.TimeFormat.Server);
            cbTimeFormatToUse.SelectedItem = App.TimeFormatToUse;
        }

        private void compaignsBindingSource_CurrentChanged(object sender, EventArgs e)
        {

        }

        private void CompaingView_Load(object sender, EventArgs e)
        {

            //foreach (Compaign compaing in App.compaigns.AllCompaigns)
            //{
            //    TreeNode compaingNode = tvCompaigns.Nodes.Add(compaing.Name);
            //    compaingNode.Tag = compaing;
            //    //compaingNode.ContextMenuStrip = contextMenuStrip1;

            //    PopulateCompaignNode(compaingNode, compaing);
            //}
            PopulateCompaignsTree();

            dtpLocalTime.Value = DateTime.Now.AddMinutes(3);
            dtpServerTime.Value = dtpLocalTime.Value.AddHours(App.TimeAdjustment);

            RefreshScreen();

            PopulateExecutingAttacks();
        }       
 
        public void PopulateCompaignsTree() 
        {
            tvCompaigns.Nodes.Clear();
            foreach (Compaign compaing in App.compaigns.AllCompaigns)
            {
                TreeNode compaingNode = tvCompaigns.Nodes.Add(compaing.Name);
                compaingNode.Tag = compaing;
                compaingNode.ImageIndex = 0;
                compaingNode.StateImageIndex = 0;

                PopulateCompaignNode(compaingNode, compaing);
            }


        }

        private void PopulateCompaignNode(TreeNode compaignNode, Compaign compaign) 
        {
          //  string targetText;
            foreach (Target target in compaign.Targets)
            {
                PopulateCompaignNode_AddTargetNode(compaignNode, target);
            }
        }

        private TreeNode PopulateCompaignNode_AddTargetNode(TreeNode compaignNode, Target target)
        {
            TreeNode targetNode;
            targetNode = compaignNode.Nodes.Add(PopulateCompaignNode_GetTargetNodeText(target));
            targetNode.Tag = target;
            targetNode.ImageIndex = 2;
            targetNode.SelectedImageIndex = 2;
            if (target.AttacksLaunched)
            {
                targetNode.ImageIndex = 3;
                targetNode.SelectedImageIndex = 3;
                targetNode.ForeColor = Color.DarkGray;
            }

            return targetNode;
        }

        private string PopulateCompaignNode_GetTargetNodeText(Target target)
        {
            string targetText;
            targetText = target.TargetVillage.VillageOwner == null ? "[abondoned]" : target.TargetVillage.VillageOwner.Name;
            targetText += " - " + target.TargetVillage.name;
            targetText += " (" + target.TargetVillage.X + "|" + target.TargetVillage.y + ") - ";
            targetText += target.Description;

            return targetText;
        }


        private void PopulateExecutingAttacks()
        {            
            dgvExecutingAttacks.Rows.Clear();

            foreach (Compaign compaing in App.compaigns.AllCompaigns)
            {
                foreach (Target target in compaing.Targets)
                {
                    if (target.AttacksLaunched)
                    {
                        foreach (Attack attack in target.Attacks)
                        {
                            int i = dgvExecutingAttacks.Rows.Add(new object[] { 
                                FormatVillageName(attack.AttackingVillage) 
                        , FormatVillageName(target.TargetVillage)
                        , attack.TravelTime
                        , attack.AttackingUnit.Name
                        , attack.TimeLaunched
                        , ""
                        , attack.LandTime //App.FormatTWEventTime(attack.LandTime)
                        , attack.Description });

                            dgvExecutingAttacks.Rows[i].Tag = attack;

                            FormatExecutingAttackRow(dgvExecutingAttacks.Rows[i]);

                        }
                    }
                }
            }

        }

        private string FormatVillageName(Village vil)
        {
            return vil.name + " (" + vil.X + "|" + vil.y + ")";
        }

        private void tvCompaigns_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ProcessTreeNode(e.Node);
 
        }

        /// <summary>
        /// the only place where attack are to be rescheduled
        /// </summary>
        private void ReScheduleAttacks(Target target)
        {
            if (scheduleBy == ScheduleBy.StartTime)
            {
                target.ScheduleAttacks(dtpLocalTime.Value);
            }
            else if (scheduleBy == ScheduleBy.LandTime)
            {
                target.ScheduleAttacksByLandTime(dtpLandTime_Local.Value);
            }
            else
            {
                throw new ArgumentException("unrecognized value of scheduleBy=" + scheduleBy.ToString());
            }

        }

        private void ProcessTreeNode(TreeNode node)
        {
            dgvAttacks.Rows.Clear();
            if (node.Tag is Target)
            {
                SetReadOnlyScheduleMode(false);
                Target target = (Target)node.Tag;
                if (target.AttacksLaunched)
                {
                    tabs.SelectedTab = tabPageExecute;
                }
                else
                {
                    tabs.SelectedTab = tabPagePlan;
                    ReScheduleAttacks(target);



                    AddTargetToList(target);
                }
            }
            else if (node.Tag is Compaign)
            {
                SetReadOnlyScheduleMode(true);
                foreach (TreeNode treeNode in node.Nodes)
                {
                    Target target = (Target)treeNode.Tag;
                    if ( !target.AttacksLaunched)
                    {
                        tabs.SelectedTab = tabPagePlan;
                        ReScheduleAttacks(target);

                        AddTargetToList(target);
                    }
                }
            }
            SortAttacksDataGrid();
        }

        private void SetReadOnlyScheduleMode(bool readOnly)
        {
            //if ( readOnly ) {
            //    tabsScheduleBy.SelectedTab = tabScheduleByStartTime;
            //}            

            bool Enabled = !readOnly;
            //tabsScheduleBy.Enabled = Enabled;

            button1.Enabled = Enabled;
            //btnExecute.Enabled = Enabled;

            //dgvAttacks.Columns[CONSTS.dgvAttacks.ColIndexes.AttackOrder].ReadOnly = readOnly;
            //dgvAttacks.Columns[CONSTS.dgvAttacks.ColIndexes.Unit].ReadOnly = readOnly;
            //dgvAttacks.Columns[CONSTS.dgvAttacks.ColIndexes.Unit].ReadOnly = readOnly;

        }

        private void AddTargetToList(Target target)
        {
            foreach (Attack attack in target.Attacks)
            {
                int i = dgvAttacks.Rows.Add(new object[] { attack.Priority
                        , FormatVillageName(attack.AttackingVillage) 
                        , FormatVillageName(target.TargetVillage)
                        , attack.TravelTimeString
                        , attack.AttackingUnit.Name
                        , App.FormatTWEventTime(attack.TimeLaunched)
                        , App.FormatTWEventTime(attack.LandTime)
                        , attack.Description });

                dgvAttacks.Rows[i].Tag = attack;

            }

        }

 

        private void dgvAttacks_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {

            if (e.ColumnIndex == 0)
            {
                //e.Cancel = true;
                //MessageBox.Show("sdsds");
            }
        }

        private void RefreshScreen()
        {
            if (tvCompaigns.SelectedNode != null)
            {
                ProcessTreeNode(tvCompaigns.SelectedNode);
            }
            else
            {
                dgvAttacks.Rows.Clear();
            }

            EnableDisableButtons();
        }

        private void EnableDisableButtons()
        {
            btnSaveChanges.Enabled = App.compaigns.AreThereChanges;
        }

        private bool scheduleUpdateNeeded = false;
        private void dgvAttacks_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewRow row = dgvAttacks.Rows[e.RowIndex];
            row.ErrorText = String.Empty;

        }


        private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
        {

        }

        private void dtpLocalTime_ValueChanged(object sender, EventArgs e)
        {
            dtpServerTime.Value = dtpLocalTime.Value.AddHours(App.TimeAdjustment);

            RefreshScreen();
        }

        private void dtpServerTime_ValueChanged(object sender, EventArgs e)
        {
            dtpLocalTime.Value = dtpServerTime.Value.AddHours(0 - App.TimeAdjustment);

        }

        private void dgvAttacks_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            System.Diagnostics.Trace.WriteLine("dgvAttacks_CellValueChanged");
            DataGridViewRow row = dgvAttacks.Rows[e.RowIndex];
            if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.Unit && row.Tag != null)
            {
                ((Attack)row.Tag).AttackingUnit = Worlds.currentWorld.Units[row.Cells[CONSTS.dgvAttacks.ColIndexes.Unit].Value.ToString()];
                RefreshScreen();
            }
            else if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.AttackOrder && row.Tag != null)
            {
                ((Attack)row.Tag).Priority = (int)row.Cells[CONSTS.dgvAttacks.ColIndexes.AttackOrder].Value;
                RefreshScreen();

                System.Diagnostics.Trace.WriteLine("dgvAttacks_CellEndEdit e.ColumnIndex=" + e.ColumnIndex.ToString());
            }
            else if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.Description && row.Tag != null)
            {
                ((Attack)row.Tag).Description = (string)row.Cells[CONSTS.dgvAttacks.ColIndexes.Description].Value;
            }

        }

        private void dgvAttacks_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            DataGridViewRow row = dgvAttacks.Rows[e.RowIndex];
            e.ThrowException = true;
            if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.AttackOrder && row.Tag != null)
            {
                MessageBox.Show("Please enter only a number in Attack Order Column.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
                e.ThrowException = false;
            }

        }

        private void dgvAttacks_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.AttackOrder)
            {
                int val;
                if (!Int32.TryParse(e.FormattedValue.ToString(), out val))
                {
                    dgvAttacks.Rows[e.RowIndex].ErrorText = "Please enter only a number in Attack Order Column.";
                    e.Cancel = true;
                }
            }

           
        }

        private void dgvAttacks_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {

            //if (dgvAttacks.CurrentCell.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.Unit)
            //{
            //    if (dgvAttacks.IsCurrentCellDirty)
            //    {
            //        dgvAttacks.CommitEdit(DataGridViewDataErrorContexts.Commit);
            //    }
            //}

            //System.Diagnostics.Trace.WriteLine("dgvAttacks_CellValueChanged");
            //DataGridViewRow row = dgvAttacks.Rows[e.RowIndex];
            //if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.Unit && row.Tag != null)
            //{
            //    ((Attack)row.Tag).AttackingUnit = Worlds.currentWorld.Units[row.Cells[CONSTS.dgvAttacks.ColIndexes.Unit].Value.ToString()];
            //    //scheduleUpdateNeeded = true;
            //    UpdateScheduleDisplay();
            //}

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (scheduleBy == ScheduleBy.StartTime)
            {
                if (DateTime.Now < dtpLocalTime.Value)
                {
                    TimeSpan timeTillSchedule = dtpLocalTime.Value - DateTime.Now;

                    lblCountDown.Text = "The above time is " + App.FormatTWDuration(timeTillSchedule) + " from now";
                    if (timeTillSchedule.TotalMinutes <= 1)
                    {
                        lblCountDown.Text += "Enter a time at least 1 minute in the future to be able to execute these attacks";
                        lblCountDown.ForeColor = Color.DarkGoldenrod;
                        btnExecute.Enabled = false;
                    }
                    else
                    {
                        lblCountDown.ForeColor = Color.Green;
                        btnExecute.Enabled = true;
                        toolTip1.SetToolTip(btnExecute, "Clicking this button will execute add the below attacks. Once this is done, you will receive notifiactions when each attack must be sent");
                    }
                }
                else
                {
                    btnExecute.Enabled = false;

                    lblCountDown.ForeColor = Color.Crimson;
                    lblCountDown.Text = "Time has expired. Enter a time in the future to be able to execute these attacks";

                }
            }
            //Schedule by arrival time
            else
            {
                List<Target> targets = null;

                //If nothing is selected
                if (this.tvCompaigns.SelectedNode == null)
                {
                    //Do nothing
                }
                else
                {   
                    if (tvCompaigns.SelectedNode.Tag is Target)
                    {
                        targets = new List<Target>(1);
                        if (((Target)tvCompaigns.SelectedNode.Tag).Attacks.Count > 0)
                        {
                            targets.Add((Target)tvCompaigns.SelectedNode.Tag);
                        }
                    }
                    else if (tvCompaigns.SelectedNode.Tag is Compaign)
                    {
                        targets = new List<Target>(tvCompaigns.SelectedNode.Nodes.Count);

                        foreach (TreeNode node in tvCompaigns.SelectedNode.Nodes)
                        {
                            if (((Target)node.Tag).Attacks.Count > 0)
                            {
                                targets.Add((Target)node.Tag);
                            }
                        }
                    }
                }

                if (targets != null && targets.Count > 0)
                {
                    Attack firstAttackToLaunch = targets[0].FirstAttackToBeLaunched;
                    Attack cur;
                    for (int i = 1; i < targets.Count; i++)
                    {
                        cur = targets[i].FirstAttackToBeLaunched;
                        if (cur != null)
                        {
                            if (firstAttackToLaunch.TimeLaunched > cur.TimeLaunched)
                            {
                                firstAttackToLaunch = cur;
                            }
                        }
                    }

                    if (firstAttackToLaunch != null)
                    {
                        if (DateTime.Now < firstAttackToLaunch.TimeLaunched)
                        {
                            TimeSpan timeTillSchedule = firstAttackToLaunch.TimeLaunched - DateTime.Now;

                            lblLandTimeMessage.Text = "1st attack must be sent in " + App.FormatTWDuration(timeTillSchedule) + " from now";
                            if (timeTillSchedule.TotalMinutes <= 1)
                            {
                                btnExecute.Enabled = false;
                                lblLandTimeMessage.ForeColor = Color.Crimson;
                                lblLandTimeMessage.Text = "Cannot land these attacks at the specified time since time to send the first attack has already exired";
                            }
                            else
                            {
                                lblLandTimeMessage.ForeColor = Color.Green;
                                btnExecute.Enabled = true;
                                toolTip1.SetToolTip(btnExecute, "Clicking this button will execute add the below attacks. Once this is done, you will receive notifiactions when each attack must be sent");
                            }
                        }
                        else
                        {
                            btnExecute.Enabled = false;

                            lblLandTimeMessage.ForeColor = Color.Crimson;
                            lblLandTimeMessage.Text = "Cannot land these attacks at the specified time since time to send the first attack has already exired";
                        }
                    }
                    else
                    {
                        btnExecute.Enabled = false;
                        lblLandTimeMessage.Text = "";
                    }
                }
                else
                {
                    lblLandTimeMessage.ForeColor = Color.Crimson;
                    lblLandTimeMessage.Text = "No attacks";
                }
            }
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            if (dgvAttacks.Rows.Count == 0)
            {
                MessageBox.Show("You have not entered any attacks on this target yet. Please first enter at least one attack.");
                return;
            }

            TimeSpan timeTillSchedule = dtpLocalTime.Value - DateTime.Now;

            string msg = "Are you sure you want to launched these attacks? PLEASE ensure that there is still time to launch all attacks";
            if (tvCompaigns.SelectedNode.Tag is Compaign)
            {
                if ( tvCompaigns.SelectedNode.Nodes.Count > 1) {
                    msg += " Also, please be aware that you have currently selected more then one attack. All the attacks under the campaign you have selected will be executed if you choose to continue";
                }
            }

            if (MessageBox.Show(msg,"Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                if (tvCompaigns.SelectedNode.Tag is Target)
                {
                    Target target = (Target)tvCompaigns.SelectedNode.Tag;
                    target.AttacksLaunched = true;
                    tvCompaigns.SelectedNode.ForeColor = Color.DarkGray;
                }
                else if (tvCompaigns.SelectedNode.Tag is Compaign)
                {
                    foreach (TreeNode treeNode in tvCompaigns.SelectedNode.Nodes)
                    {
                        Target target = (Target)treeNode.Tag;
                        target.AttacksLaunched = true;
                        treeNode.ForeColor = Color.DarkGray;
                    }
                }

                RefreshScreen();
                PopulateExecutingAttacks();
                tabs.SelectedTab = tabPageExecute;
            }
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

            TreeNode node = tvCompaigns.SelectedNode;

            itemDeleteCompaign.Enabled = false;
            itemDeleteTarget.Enabled = false;
            itemAddTarget.Enabled = false;
            itemRenameCompaign.Enabled = false;
            itemModifyTarget.Enabled = false;
            itemCopyTarget.Enabled = false;
            itemPasteTarget.Enabled = false;
            itemLaunchAgain.Enabled = false;
            itemCancelAttacks.Enabled = false;

            if (tvCompaigns.SelectedNode != null)
            {
                if (node.Tag is Target)
                {
                    itemDeleteTarget.Enabled = true;
                    itemAddTarget.Enabled = true;
                    itemModifyTarget.Enabled = true;
                    itemCopyTarget.Enabled = true;

                    if (((Target)node.Tag).AttacksLaunched)
                    {
                        if (((Target)node.Tag).AttacksLaunched_AllAttacksAway)
                        {
                            itemLaunchAgain.Enabled = true;
                        }
                        else
                        {
                            itemCancelAttacks.Enabled = true;
                        }
                    }
                }
                else if (node.Tag is Compaign)
                {
                    itemDeleteCompaign.Enabled = true;
                    itemRenameCompaign.Enabled = true;
                    itemAddTarget.Enabled = true;
                }

                if (targetToCopy != null)
                {
                    itemPasteTarget.Enabled = true;
                }
            }
        }

        private void addCompaignToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Compaign compaign = App.compaigns.Add("New campaign");
            TreeNode compaignNode = tvCompaigns.Nodes.Add(compaign.Name);
            compaignNode.Tag = compaign;

            compaignNode.BeginEdit();

        }

        private void tvCompaigns_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (!(e.Node.Tag is Compaign))
            {
                e.CancelEdit = true;
            }
        }

        private void tvCompaigns_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (!(e.Node.Tag is Compaign))//sanity check                
            {
                e.CancelEdit = true;
                return;
            }

            if (e.Label != null)
            {
                ((Compaign)e.Node.Tag).Name = e.Label;
                EnableDisableButtons();
            }

        }

        private void itemDeleteCompaign_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCompaigns.SelectedNode;
            TreeNode nodeToSelectAfter = null ;

            if (node.Tag is Target)
            {
                if (MessageBox.Show("Deleting this Target will delete ALL attacks you may have.\n\nAre you sure?"
                    , "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                {
                    nodeToSelectAfter = node.PrevNode;
                    ((Target)node.Tag).Delete();
                    node.Remove();
                }
            }
            else if (node.Tag is Compaign)
            {
                if (MessageBox.Show("Deleting this campaign will delete ALL targets, any plans/attacks for this target as well as all executing attacks.\n\nAre you sure?","Delete?",MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                {
                    ((Compaign)node.Tag).Delete();
                    node.Remove();
                }
            }
            PopulateExecutingAttacks();
            RefreshScreen();


            if (nodeToSelectAfter != null)
            {
                tvCompaigns.SelectedNode = nodeToSelectAfter;
                nodeToSelectAfter.Expand();
            }

            //deleteding an attack that is in a clipboard can be very bad (as this attack can no longer be accessed) so 
            //  we clear the clipboard. Not the best solution, but will have to do for now. 
            InvalidateClipboard();
        }

        private void itemDeleteTarget_Click(object sender, EventArgs e)
        {
            itemDeleteCompaign_Click(sender, e);
        }

        private void dgvAttacks_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            Attack attack = (Attack)e.Row.Tag;

            attack.Delete();

            //deleteding an attack that is in a clipboard can be very bad (as this attack can no longer be accessed) so 
            //  we clear the clipboard. Not the best solution, but will have to do for now. 
            InvalidateClipboard();
        }

        private void InvalidateClipboard()
        {
            targetToCopy = null;
            attacksToCopy = null;
        }

        private void dgvAttacks_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
        {
            RefreshScreen();
        }

        private void dgvAttacks_UserAddedRow(object sender, DataGridViewRowEventArgs e)
        {
            MessageBox.Show("added");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCompaigns.SelectedNode;
            Target target;

            if (tvCompaigns.Nodes.Count == 0)
            {
                MessageBox.Show("You do not have any campaigns defined. Right click the campaign tree and choose 'Add campaign' first."
                    , "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;

            }
            if (node == null)
            {
                MessageBox.Show("Selected a target first."
                    , "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else if (node.Tag is Compaign)
            {
                if (node.Nodes.Count == 0)
                {
                    MessageBox.Show("You do not have any targets defined in the selected campaign. Right click the campaign and choose 'Add Target' first."
                        , "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                else if (node.Nodes.Count > 1)
                {
                    MessageBox.Show("Your currently selected campaign '"
                        + ((Compaign)node.Tag).Name + "', has more then one target. Please select a target that you wish to add an attack for."
                        , "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                else
                {
                    // must be only one target then
                    target = (Target)node.Nodes[0].Tag;
                }
            }
            else if (node.Tag is Target)
            {
                target = (Target)node.Tag;
            }
            else//sanity check. 
            {
                return; 
            }

            AddAttack frm = new AddAttack();
            frm.Owner = this;
            frm.udAttackOrder.Value = 10 + dgvAttacks.Rows.Count;
            frm.ShowDialog();
            if (frm.DialogResult == DialogResult.OK)
            {
                target.AddAttack(frm.selectedVillage
                    , Convert.ToInt32(frm.udAttackOrder.Value)
                    , (Unit)frm.cbUnit.SelectedItem
                    , frm.txtDescription.Text);
                RefreshScreen();
            }


        }

        private void tvCompaigns_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                tvCompaigns.SelectedNode = e.Node;
                
            }
        }

        private void itemAddTarget_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCompaigns.SelectedNode;
            TreeNode nodeToSelectAfter = null;

            Compaign compaign;

            if (node.Tag is Compaign)
            {
                compaign = (Compaign)node.Tag;
                nodeToSelectAfter = node;
            }
            else if (node.Tag is Target)
            {
                compaign = (Compaign)node.Parent.Tag;
                nodeToSelectAfter = node.Parent;

            }
            else
            {
                return;// Add Target should really be disabled in this case....
            }



            AddTarget frm = new AddTarget();
            frm.Owner = this;
            frm.ShowDialog();

            if (frm.DialogResult == DialogResult.OK)
            {
                Target t = compaign.AddTarget(frm.selectedVillage, frm.txtDescription.Text);
                TreeNode newTarget = PopulateCompaignNode_AddTargetNode(nodeToSelectAfter, t);
                tvCompaigns.SelectedNode = newTarget;
                //RefreshScreen();
                
            }
        }

        private void btnSaveChanges_Click(object sender, EventArgs e)
        {
            App.compaigns.Save();
            EnableDisableButtons();

        }

        private void CompaingView_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                this.Visible = false;
                e.Cancel = true;
            }
            App.compaigns.Save();
        }

        // Search predicate
        private Attack attackToFind;
        private bool AttackEquals(int a)
        {
            if (a.Equals(attackToFind.AttackID))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        List<int> lanuchAttackNotified = new List<int>();


        private void timerLaunchedAttacks_Tick(object sender, EventArgs e)
        {
            bool reSort = false;
            foreach (DataGridViewRow row in dgvExecutingAttacks.Rows)
            {
                Attack attack = (Attack)row.Tag;

                reSort = FormatExecutingAttackRow(row) || reSort;
                if (DateTime.Now < attack.TimeLaunched)
                {
                    TimeSpan timeTillLaunch = attack.TimeLaunched - DateTime.Now;
                    attackToFind = attack;
                    if (!attack.Launched 
                        && timeTillLaunch.TotalMinutes < 5 
                        && !lanuchAttackNotified.Exists(new Predicate<int>(AttackEquals)))
                    {
                        lanuchAttackNotified.Add(attack.AttackID);
                        LaunchAttack frm = new LaunchAttack(attack);
                        frm.Show();
                    }
                }
            }

            SortExecutingDataGrid();
        }

        private enum ExecutingAttackStatus
        {
            expired,
            sent,
            normal
        }
        private bool FormatExecutingAttackRow(DataGridViewRow row)
        {
            bool reSort = false;
            Attack attack = (Attack)row.Tag;
            if (attack.Launched)
            {
                if (row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value.ToString() == string.Empty
                    || (TimeSpan)row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value != TimeSpan.MaxValue)
                {
                    row.DefaultCellStyle.ForeColor = Color.DarkGray;
                    row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value = TimeSpan.MaxValue;
                    reSort = true;
                }
            }
            else if (DateTime.Now < attack.TimeLaunched)
            {
                TimeSpan timeTillLaunch = attack.TimeLaunched - DateTime.Now;

                row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value = timeTillLaunch;//App.FormatTWDuration(timeTillLaunch);
            }
            else
            {
                if (row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value.ToString() == string.Empty
                    || (TimeSpan)row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value != TimeSpan.MinValue)
                {
                    row.DefaultCellStyle.ForeColor = Color.Crimson;
                    row.Cells[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn].Value = TimeSpan.MinValue;
                    reSort = true;
                }
            }

            return reSort;
        }

        
        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            timerLaunchedAttacks.Interval = Convert.ToInt32( numericUpDown1.Value) * 1000;
        }

        private void timerSave_Tick(object sender, EventArgs e)
        {
            if (App.compaigns.AreThereChanges)
            {
                App.compaigns.Save();
            }
        }

        private void dgvExecutingAttacks_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.ColumnIndex == CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn )
            {
                DataGridViewTextBoxCell cell = (DataGridViewTextBoxCell)dgvExecutingAttacks.Rows[e.RowIndex].Cells[e.ColumnIndex];
                DataGridViewRow row = dgvExecutingAttacks.Rows[e.RowIndex];
                Attack attack = (Attack)row.Tag;
                if (attack != null)
                {
                    if (attack.Launched)
                    {
                        e.Value = "Sent";
                    }
                    else if (((TimeSpan)cell.Value) <= TimeSpan.Zero)
                    {
                        e.Value = "Expired!";
                    }
                    else
                    {
                        e.Value = App.FormatTWDuration((TimeSpan)e.Value);
                    }
                }
            }
            else if (e.ColumnIndex == CONSTS.dgvExecutingAttacks.ColIndexes.LandTime)
            {
                if (e.Value != null && e.Value.ToString() != String.Empty) 
                {
                    e.Value = App.FormatTWEventTime((DateTime)e.Value);
                }
            }
            else if (e.ColumnIndex == CONSTS.dgvExecutingAttacks.ColIndexes.LaunchTime)
            {
                if (e.Value != null && e.Value.ToString() != String.Empty)
                {
                    e.Value = App.FormatTWEventTime((DateTime)e.Value);
                }
            }
            else if (e.ColumnIndex == CONSTS.dgvExecutingAttacks.ColIndexes.Duration)
            {
                DataGridViewRow row = dgvExecutingAttacks.Rows[e.RowIndex];
                Attack attack = (Attack)row.Tag;
                if (attack != null)
                {
                    e.Value = attack.TravelTimeString;
                }
            }
        }

        private void SortExecutingDataGrid() 
        {
            DataGridViewColumn sortCol=null;
            ListSortDirection direction = ListSortDirection.Ascending;

            if (dgvExecutingAttacks.SortedColumn == null)
            {

                sortCol = dgvExecutingAttacks.Columns[CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn];
                direction = ListSortDirection.Ascending;

            } else if (dgvExecutingAttacks.SortedColumn != null && dgvExecutingAttacks.SortedColumn.Index == CONSTS.dgvExecutingAttacks.ColIndexes.LaunchIn)
            {
                sortCol = dgvExecutingAttacks.SortedColumn;
                direction = dgvExecutingAttacks.SortOrder == SortOrder.Ascending ? ListSortDirection.Ascending : ListSortDirection.Descending;
            }
            if (sortCol != null)
            {
                dgvExecutingAttacks.Sort(sortCol, direction);
            }

        }

        private void SortAttacksDataGrid()
        {
            DataGridViewColumn sortCol=null;
            ListSortDirection direction = ListSortDirection.Ascending;

            if (dgvAttacks.SortedColumn == null)
            {

                sortCol = dgvAttacks.Columns[CONSTS.dgvAttacks.ColIndexes.LandTime];
                direction = ListSortDirection.Ascending;
            }
            else
            {
                sortCol = dgvAttacks.SortedColumn;
                direction = dgvAttacks.SortOrder == SortOrder.Ascending ? ListSortDirection.Ascending : ListSortDirection.Descending;
            }
            dgvAttacks.Sort(sortCol, direction);

        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            WindowsApplication4.Properties.Settings.Default.LandTimeDifference = updownTimeBetweenLandings.Value;
            RefreshScreen();
        }

        private void tabPagePlan_Click(object sender, EventArgs e)
        {
        
        }

        private void itemRenameCompaign_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCompaigns.SelectedNode;

            if (node.Tag is Compaign)
            {
                node.BeginEdit();
            }
        }

        private void itemModifyTarget_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCompaigns.SelectedNode;

            Target targetToModify;
            if (node.Tag is Target)
            {
                targetToModify = (Target)node.Tag;
                AddTarget frm = new AddTarget(targetToModify);
                frm.Owner = this;
                frm.ShowDialog();

                node.Text = PopulateCompaignNode_GetTargetNodeText(targetToModify);
                RefreshScreen();
                
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {

            ie browser = new ie("http://www.twplus2.com/demo/Tutorials.aspx");
            browser.Show();
        }

        private void tabsScheduleBy_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabsScheduleBy.SelectedTab == tabScheduleByLandTime)
            {
                //if (tvCompaigns.SelectedNode.Tag is Compaign)
                //{
                //    tabs.
                //}
                scheduleBy = ScheduleBy.LandTime;
                RefreshScreen();
            }
            else
            {
                scheduleBy = ScheduleBy.StartTime;
                RefreshScreen();
            }
        }

        private void dtpLandTime_Local_ValueChanged(object sender, EventArgs e)
        {
            dtpLandTime_Server.Value = dtpLandTime_Local.Value.AddHours(App.TimeAdjustment);

            RefreshScreen();

        }

        private void dtpLandTime_Server_ValueChanged(object sender, EventArgs e)
        {
            dtpLandTime_Local.Value = dtpLandTime_Server.Value.AddHours(0 - App.TimeAdjustment);
        }

        private void tabs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tvCompaigns.SelectedNode != null && tvCompaigns.SelectedNode.Tag is Target)
            {
                if (((Target)tvCompaigns.SelectedNode.Tag).AttacksLaunched)
                {
                    tabs.SelectedTab = tabPageExecute;
                }
            }
        }

        private void btnTMailSchedule_Click(object sender, EventArgs e)
        {
            string txt = String.Empty;
            foreach(DataGridViewRow row in dgvAttacks.Rows) 
            {
                txt += ((Attack)row.Tag).ToTMailString() + Environment.NewLine;
            }

            TMail frm = new TMail(txt);
            frm.Show();
        }

        private void cbTimeFormatToUse_SelectedIndexChanged(object sender, EventArgs e)
        {
            App.TimeFormatToUse = (App.TimeFormat)cbTimeFormatToUse.SelectedItem;
            RefreshScreen();
        }

        private void dgvAttacks_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.ColumnIndex == CONSTS.dgvAttacks.ColIndexes.Launch)
            {
                DataGridViewTextBoxCell cell = (DataGridViewTextBoxCell)dgvAttacks.Rows[e.RowIndex].Cells[e.ColumnIndex];
                DataGridViewRow row = dgvAttacks.Rows[e.RowIndex];
                Attack attack = (Attack)row.Tag;
                if (attack.TimeLaunched < DateTime.Now)
                {
                    //row.DefaultCellStyle.ForeColor = Color.Crimson;
                    cell.Style.ForeColor= Color.Crimson;

                }
                else if (attack.TimeLaunched < DateTime.Now.AddMinutes(1)) 
                {
                    cell.Style.ForeColor = Color.DarkGoldenrod;
                }
            }

        }

        private void coToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tvCompaigns.SelectedNode.Tag is Target)
            {
                targetToCopy = (Target)tvCompaigns.SelectedNode.Tag;
            }
        }

        private void pasteTargetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Compaign compaign = null;
            TreeNode campaignNode = null;
            if (tvCompaigns.SelectedNode.Tag is Target)
            {
                compaign = (Compaign)tvCompaigns.SelectedNode.Parent.Tag;
                campaignNode = tvCompaigns.SelectedNode.Parent;
            }
            else if (tvCompaigns.SelectedNode.Tag is Compaign)
            {
                compaign = (Compaign)tvCompaigns.SelectedNode.Tag;
                campaignNode = tvCompaigns.SelectedNode;
            }

            if (compaign != null && targetToCopy != null)
            {
                Target newTarget = targetToCopy.Copy(compaign);
                TreeNode newTargetNode = PopulateCompaignNode_AddTargetNode(campaignNode, newTarget);
                tvCompaigns.SelectedNode = newTargetNode;
            }
        }


        private void contextMenuStrip_AttackSchedule_Opening(object sender, CancelEventArgs e)
        {
            itemCopyAttack.Enabled = false;
            itemPasteAttack.Enabled = false;
            itemPasteAttacksSpecial.Enabled = false;

            if (dgvAttacks.SelectedRows.Count > 0)
            {
                itemCopyAttack.Enabled = true;
            }

            if (attacksToCopy != null)
            {
                if (tvCompaigns.SelectedNode != null && tvCompaigns.SelectedNode.Tag is Target)
                {
                    itemPasteAttack.Enabled = true;
                    itemPasteAttacksSpecial.Enabled = true;
                }
            }
        }

        private void itemCopyAttack_Click(object sender, EventArgs e)
        {
            if (dgvAttacks.SelectedRows.Count >0)
            {
                attacksToCopy = new List<Attack>(dgvAttacks.SelectedRows.Count);
                foreach (DataGridViewRow row in dgvAttacks.SelectedRows)
                {
                    attacksToCopy.Add((Attack)row.Tag);
                }
            }
        }

        private void itemPasteAttack_Click(object sender, EventArgs e)
        {
            if (attacksToCopy != null)
            {
                if (tvCompaigns.SelectedNode != null && tvCompaigns.SelectedNode.Tag is Target)
                {
                    Target target = (Target)tvCompaigns.SelectedNode.Tag;

                    foreach(Attack attack in attacksToCopy) 
                    {
                        target.AddAttack(attack.AttackingVillage, attack.Priority, attack.AttackingUnit, attack.Description);
                    }
                }
            }

            RefreshScreen();

        }

        private void itemPasteAttacksAsFakes_Click(object sender, EventArgs e)
        {
            if (attacksToCopy != null)
            {
                if (tvCompaigns.SelectedNode != null && tvCompaigns.SelectedNode.Tag is Target)
                {
                    Target target = (Target)tvCompaigns.SelectedNode.Tag;

                    foreach (Attack attack in attacksToCopy)
                    {
                        target.AddAttack(attack.AttackingVillage, attack.Priority, Worlds.currentWorld.Units["Ram"], "FAKE");
                    }
                }
            }
            RefreshScreen();

        }

        //private void dgvAttacks_MouseDown(object sender, MouseEventArgs e)
        //{
        //    if (e.Button == MouseButtons.Right)
        //    {
        //        DataGridView.HitTestInfo info = dgvAttacks.HitTest(e.X, e.Y);
        //        if (info.RowIndex != -1)
        //        {
        //            dgvAttacks.Rows[info.RowIndex].Selected = true;
        //        }
        //    }

        //}

        //DateTime lastLandTime = DateTime.MaxValue;
        //private void dtpLandTimeLocal_ValueChanged(object sender, EventArgs e)
        //{
        //    if (lastLandTime != DateTime.MaxValue)
        //    {
        //        dtpLandTimeServer.Value = dtpLandTimeLocal.Value.AddHours(App.TimeAdjustment);
        //        TimeSpan diff = dtpLandTimeLocal.Value - lastLandTime;
        //        dtpLocalTime.Value = dtpLocalTime.Value.Add(diff);
        //    }
        //    lastLandTime = dtpLandTimeLocal.Value;
        //    dtpLandTimeServer.Value = dtpLandTimeLocal.Value.AddHours(App.TimeAdjustment);
        //}

        //private void dtpLandTimeServer_ValueChanged(object sender, EventArgs e)
        //{
        //    dtpLandTimeLocal.Value = dtpLandTimeServer.Value.AddHours(0 - App.TimeAdjustment);

        //}

        //private void cbScheduleByLand_CheckedChanged(object sender, EventArgs e)
        //{
        //    SetScheduleBy(cbScheduleByLand.Checked ? ScheduleBy.LandTime : ScheduleBy.StartTime);
        //}

        //private void checkBox1_CheckedChanged(object sender, EventArgs e)
        //{
        //    SetScheduleBy(cbScheduleByStartTime.Checked ? ScheduleBy.StartTime : ScheduleBy.LandTime);
        //}

   
        //private ScheduleBy scheduleBy;
        //private void SetScheduleBy(ScheduleBy scheduleBy)
        //{
        //    this.scheduleBy = scheduleBy;

        //    if (scheduleBy == ScheduleBy.LandTime) 
        //    {
        //        cbScheduleByStartTime.Enabled = false;
        //        gbAttackStartTime.Enabled = false;

        //        cbScheduleByLand.Checked = true;
        //        gbLandTime.Enabled = true;
        //    } else {
        //        cbScheduleByStartTime.Enabled = true;
        //        gbAttackStartTime.Enabled = true;

        //        cbScheduleByLand.Checked = false;
        //        gbLandTime.Enabled = false;

        //    }
        //}


        #region ICampaigns Members

        Compaign ICampaigns.CurrentCampaign
        {
            get 
            {
                TreeNode node = tvCompaigns.SelectedNode;
                Compaign campaign = null;

                if (node != null)
                {
                    if (node.Tag is Compaign)
                    {
                        campaign = (Compaign)node.Tag;
                    }
                    else if (node.Tag is Target)
                    {
                        campaign = (Compaign)node.Parent.Tag;
                    }
                }

                return campaign;
            
            }
        }

        Target ICampaigns.CurrentTarget
        {
            get {

                TreeNode node = tvCompaigns.SelectedNode;
                Target target = null; ;

                if (node != null)
                {

                    if (node.Tag is Target)
                    {
                        target = (Target)node.Tag;
                    }
                }
                return target;

            }
        }

        void ICampaigns.AddAttack(Village village)
        {
            TreeNode node = tvCompaigns.SelectedNode;
            Target target= null;

            if (node == null)
            {
                //  this should never occur!
                return;
            }
                if (node.Tag is Compaign)
                {
                    //  this should never occur!
                    return;
                }
            //
            // so node is not null and node.Tag must be of type Target
            //
           target = (Target)node.Tag;

            AddAttack frm = new AddAttack(village);
            frm.Owner = this;
            frm.udAttackOrder.Value = 10 + dgvAttacks.Rows.Count;
            frm.ShowDialog();
            if (frm.DialogResult == DialogResult.OK)
            {
                target.AddAttack(frm.selectedVillage
                    , Convert.ToInt32(frm.udAttackOrder.Value)
                    , (Unit)frm.cbUnit.SelectedItem
                    , frm.txtDescription.Text);
                RefreshScreen();
            }

        }


        void ICampaigns.AddTarget(Village village)
        {
            TreeNode node = tvCompaigns.SelectedNode;
            TreeNode nodeToSelectAfter = null;
            Compaign campaign = null;

            //
            // if no selected campaign, create a new one, otherwise, add target to the selected campaign
            //
            if (node != null)
            {
                if (node.Tag is Compaign)
                {
                    campaign = (Compaign)node.Tag;
                    nodeToSelectAfter = node;
                }
                else if (node.Tag is Target)
                {
                    campaign = (Compaign)node.Parent.Tag;
                    nodeToSelectAfter = node.Parent;
                }
            }
            else
            {
                campaign = App.compaigns.Add("New campaign");
                TreeNode compaignNode = tvCompaigns.Nodes.Add(campaign.Name);
                compaignNode.Tag = campaign;
                nodeToSelectAfter = compaignNode;
            }

            AddTarget frm = new AddTarget(village);
            frm.Owner = this;
            frm.ShowDialog();

            if (frm.DialogResult == DialogResult.OK)
            {
                Target t = campaign.AddTarget(frm.selectedVillage, frm.txtDescription.Text);
                TreeNode newTarget = PopulateCompaignNode_AddTargetNode(nodeToSelectAfter, t);
                tvCompaigns.SelectedNode = newTarget;
            }

        }

        #endregion

        private void itemLaunchAgain_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCompaigns.SelectedNode;
            Target target = null;

            if (node == null)
            {
                //  this should never occur!
                return;
            }
            if (node.Tag is Compaign)
            {
                //  this should never occur!
                return;
            }

            target = (Target)node.Tag;
            target.CancelAttack();
            node.ForeColor = Color.Black;

            RefreshScreen();
            PopulateExecutingAttacks();
            tabs.SelectedTab = tabPagePlan;
        }
    }
}